<?php

namespace App\Service\Cruise\Merchant;

use App\Http\Resources\Cruise\ShopSelfCheck\Merchant\ReportListV2Resource;
use App\Library\Rms\RmsShopApi;
use App\Library\Rms\RmsUserApi;
use App\Models\Check\CruiseCheckScanCodeLogModel;
use App\Models\Cruise\CruiseCheckDetailModel;
use App\Models\Cruise\CruiseCheckRectifyModel;
use App\Models\Cruise\CruiseCheckSelfDetailModel;
use App\Models\Cruise\CruiseCheckSelfTaskModel;
use App\Models\Cruise\CruiseOrderModel;
use App\Models\Cruise\CruiseTemplateModel;
use App\Models\Kms\User\KmsUser;
use App\Models\OpenShop\Common\OpenShopOrderManagerModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Service\BaseService;
use App\Service\Cruise\Check\CruiseCheckDetailService;
use App\Service\Cruise\Check\CruiseOrderService;
use Carbon\Carbon;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Database\Eloquent\Builder;

class CruiseCheckService extends BaseService
{

    /**
     * 获得扫描结果
     * @param int $shopId
     * @param int $userId
     * @param int $managerUserId
     * @param int $time
     * @return mixed|void|null
     */
    public static function getQrCodeInfo(int $shopId, int $userId, int $managerUserId, int $time)
    {
        //添加扫描记录
        CruiseCheckScanCodeLogModel::insertData($shopId, $userId, $managerUserId, ($time < time() ? CruiseCheckScanCodeLogModel::STATUS_OVER : CruiseCheckScanCodeLogModel::STATUS_OK));
        //过期结束
        if (!$managerUserId || !$time) {
            return self::throwErr('二维码解析失败，请联系管理员');
        }
        if ($time < time()) {
            return self::throwErr('二维码已过期，请重新获取');
        }
        //门店督导ID
        $shopManagerUserId = 0;
        $mainProcessModel  = OpenShopMainProcessModel::query()
            ->where('shopId', $shopId)
            ->with(['orderManagerRel'])
            ->first();
        if (null != $mainProcessModel) {
            foreach ($mainProcessModel->orderManagerRel as $orderManager) {
                if ($orderManager->type == OpenShopOrderManagerModel::MANAGER_TYPE_5) {
                    $shopManagerUserId = $orderManager->managerUid;
                    break;
                }
            }
        }

        $userInfo = array_column((new RmsUserApi())->getUserInfoByIds([$managerUserId, $shopManagerUserId])['data'] ?? [], null, 'id');
        return [
            'name'             => $userInfo[$managerUserId]['username'] ?? '-',
            'number'           => CruiseOrderService::getCheckNoByUserId($managerUserId),
            'position'         => '稽核专员',
            'photo'            => picturePath(($userInfo[$managerUserId]['photo'] ?? '4b/07/1e16179f2dfe445f9eaa559e81d204fd6c6f70049642a72dfd42108990dd.jpg')),
            'supervisorMobile' => $userInfo[$shopManagerUserId]['mobile'] ?? '',
            'supervisorName'   => $userInfo[$shopManagerUserId]['name'] ?? '',
        ];
    }

    /**
     * @throws GuzzleException
     */
    public static function getCheckDetailList(int $shopId, int $pageSize, int $pageNum, $status, int $templateType): array
    {
        $orderPermission = [
            'isAll' => true,
        ];
        return CruiseCheckDetailService::getCheckDetailList($orderPermission, $pageSize, $pageNum, '', '', $status, '', 0, 0, $templateType, $shopId);
    }

    /**
     * 门店任务名称列表
     * @param $pageSize
     * @param $pageNum
     * @param $shopId
     * @return array
     */
    public static function taskNameList($pageSize, $pageNum, $shopId): array
    {
        // 根据shopId获得自检任务ID
        $paginator = CruiseOrderModel::query()
            ->orderByDesc('id')
            ->where('type', CruiseTemplateModel::TYPE_8)
            ->where('shopId', $shopId)
            ->paginate($pageSize, ['*'], 'pageNum', $pageNum);

        $list = [];
        $paginator->map(function (CruiseOrderModel $cruiseOrderModel) use (&$list){
            $list[] = [
                'id'   => $cruiseOrderModel->id,
                'name' => $cruiseOrderModel->getTaskName(),
            ];
        });

        return [
            'list'           => $list,
            'count'          => $paginator->total(),
            'pageNum'        => $pageNum,
            'pageSize'       => $pageSize,
        ];
    }


    /**
     * 获取自检报告列表
     */
    public static function getSelfCheckReportList(
        int $shopId,
        int $pageSize,
        int $pageNum,
        string $status,
        int $templateType,
        string $startDate,
        string $endDate,
        int $cruiseOrderId,
        int $sysTemplate
    ): array
    {
        // 不判断权限
        $orderPermission = ['isAll' => true];

        $basicOrderIdSql = CruiseCheckDetailService::getBasicPermissionSql($templateType, '', '', 0, $orderPermission, $shopId);

        $cruiseCheckDetailModel = CruiseCheckDetailModel::query()
            ->whereRaw("orderId in (" . $basicOrderIdSql . ")")
            ->when($cruiseOrderId, function ($query) use ($cruiseOrderId) {
                $query->where('orderId', $cruiseOrderId);
            })
            ->when($sysTemplate, function ($query) use ($sysTemplate) {
                $query->where('sysTemplate', $sysTemplate);
            })
            ->whereIn('reportResult', [CruiseCheckDetailModel::REPORT_RESULT_QUALIFIED, CruiseCheckDetailModel::REPORT_RESULT_UNQUALIFIED])
            ->when(strlen($startDate) && strlen($endDate), function ($query) use ($startDate, $endDate) {
                $startDate = str_replace(['年', '月', '日', '.'], '', $startDate);
                $endDate   = str_replace(['年', '月', '日', '.'], '', $endDate);
                $query->whereBetween('createdAt', [Carbon::parse($startDate)->startOfDay()->timestamp, Carbon::parse($endDate)->endOfDay()->timestamp]);
            });

        $totalCount  = (clone $cruiseCheckDetailModel)->count();
        $qualified   = (clone $cruiseCheckDetailModel)->where('reportResult', CruiseCheckDetailModel::REPORT_RESULT_QUALIFIED)->count();
        $unqualified = (clone $cruiseCheckDetailModel)->where('reportResult', CruiseCheckDetailModel::REPORT_RESULT_UNQUALIFIED)->count();

        $paginator = $cruiseCheckDetailModel
            ->when(strlen($status), function ($query) use ($status) {
                $query->where('reportResult', $status);
            })
            ->with([
                'cruiseOrderRel.cruiseCheckSelfTaskRel',
                'cruiseCheckRectify' => function ($query) {
                    $query->whereIn('status', [CruiseCheckRectifyModel::STATUS_WAIT_SUBMIT, CruiseCheckRectifyModel::STATUS_WAIT_AUDIT]);
                },
            ])
            ->orderByDesc('updatedAt')
            ->paginate($pageSize, ['*'], 'pageNum', $pageNum);

        $list = [];
        $handlerIdList = [];
        $paginator->map(function (CruiseCheckDetailModel $cruiseCheckDetailModel) use (&$list, &$handlerIdList){

            $cruiseCheckSelfTaskRel = optional($cruiseCheckDetailModel->cruiseOrderRel)->cruiseCheckSelfTaskRel;
            // 自检周期 执行时段
            $cycle     = '-';
            $timeFrame = '-';

            if ($cruiseCheckSelfTaskRel != null) {
                $cycle     = Carbon::createFromTimestamp($cruiseCheckSelfTaskRel->taskStartTime)->toDateString() . '至' . Carbon::createFromTimestamp($cruiseCheckSelfTaskRel->taskEndTime)->toDateString();
                $timeFrame = Carbon::createFromFormat('H:i:s', $cruiseCheckSelfTaskRel->executeStartHis)->format('H:i') . '-' .  Carbon::createFromFormat('H:i:s', $cruiseCheckSelfTaskRel->executeEndHis)->format('H:i');
            }

            $handlerIdList[] = $handlerId = (int)optional($cruiseCheckDetailModel->cruiseOrderRel)->handlerId;

            // 获取审批中的状态
            $statusText = CruiseCheckDetailModel::REPORT_RESULT_MAPPING[$cruiseCheckDetailModel->reportResult] ?? '-';
            if ($cruiseCheckDetailModel->reportResult == CruiseCheckDetailModel::REPORT_RESULT_INIT && $cruiseCheckDetailModel->submitTime > 0) {
                $statusText = '审核中';
            }

            $list[] = [
                'id'           => $cruiseCheckDetailModel->id,
                'cycle'        => $cycle,
                'timeFrame'    => $timeFrame,
                'shopInfo'     => '',
                'code'         => $cruiseCheckDetailModel->code,
                'statusText'   => $statusText,
                'status'       => $cruiseCheckDetailModel->reportResult,
                'totalNum'     => $cruiseCheckDetailModel->totalNum,
                'tip'          => '',
                'rectifyCount' => count($cruiseCheckDetailModel->cruiseCheckRectify),
                'failNum'      => $cruiseCheckDetailModel->failNum,
                'updatedAt'    => $cruiseCheckDetailModel->updatedAt->toDateTimeString(),
                'handler'      => $cruiseCheckDetailModel->dealName,
                'companyName'  => '',
                'handlerId'    => $handlerId,
                'taskName'     => $cruiseCheckDetailModel->cruiseOrderRel->getTaskName($cruiseCheckDetailModel->taskId),
                'qualityScore' => $cruiseCheckDetailModel->qualityScore,  //督导评分
                'handlerName'  => $cruiseCheckDetailModel->dealName,
            ];
        });

        // $handlerNameList = (new RmsUserApi())->getUserInfoByIds($handlerIdList, ['id', 'username'])['data'] ?? [];
        // $handlerNameList = array_column($handlerNameList, 'username', 'id');

        return [
            'list'        => $list,
            'count'       => $paginator->total(),
            'pageNum'     => $pageNum,
            'pageSize'    => $pageSize,
            'totalCount'  => $totalCount,
            'qualified'   => $qualified,
            'unqualified' => $unqualified,
        ];
    }

    /**
     * 二级模板返回
     *
     * @param int $templateType
     * @return array[]
     */
    public static function systemTemplate(int $templateType): array
    {
        return [
            "systemTemplate" => collect(CruiseTemplateModel::TEMPLATE_TYPES[$templateType] ?? [])
                ->map(function ($sysTemplate) {
                    return [
                        "key"   => CruiseTemplateModel::SYS_TEMPLATE_TEXT[$sysTemplate] ?? "",
                        "value" => $sysTemplate
                    ];
                })->values()->toArray()
        ];
    }

    /**
     * 门店自检报告V2
     *
     * @param object $params
     * @return array
     */
    public static function getSelfCheckReportListV2(object $params): array
    {
        $baseQuery = CruiseCheckSelfDetailModel::query()
                                               ->with([
                                                   "cruiseCheckSelfTaskRel" => function ($query) {
                                                       $query->select(["id", "name", "rule"]);
                                                   }
                                               ])
                                               ->where("templateType", CruiseTemplateModel::TYPE_8)
                                               ->when(checkFieldLen($params, "sysTemplate"),
                                                   function ($query) use ($params) {
                                                       $query->where("sysTemplate", $params->sysTemplate);
                                                   })
                                               ->where("shopId", $params->shopId)
                                               ->where("cruiseOrderId", ">", 0)
                                               ->when(checkFieldLen($params, "state"), function ($query) use ($params) {
                                                   switch ($params->state) {
                                                       case CruiseOrderModel::STATUS_INIT:// 已完成&已过期
                                                           $query->where(function ($query) use ($params){
                                                               $query->whereHas('cruiseOrderRel',function ($_query)use ($params){
                                                                   $_query->where(
                                                                       'shopId',$params->shopId
                                                                   )->whereIn('status',[
                                                                       CruiseOrderModel::STATUS_NOT_REVIEW,
                                                                       CruiseOrderModel::STATUS_AUDIT_OK,
                                                                       CruiseOrderModel::STATUS_AUDIT_ERROR,
                                                                       CruiseOrderModel::STATUS_EXPIRED
                                                                   ]);
                                                               });//->orWhere('executeEndTime','<',time());
                                                           });
                                                           break;
                                                       case CruiseOrderModel::STATUS_NOT_REVIEW:// 已提交
                                                           $query->where(function ($query) use ($params){
                                                               $query->whereHas('cruiseOrderRel',function ($_query)use ($params){
                                                                   $_query->where(
                                                                       'shopId',$params->shopId
                                                                   )->where('status',CruiseOrderModel::STATUS_NOT_REVIEW);
                                                               });
                                                           });
                                                           break;
                                                       case CruiseOrderModel::STATUS_EXPIRED:// 已过期
                                                           $query->where(function ($query) use ($params){
                                                               $query->whereHas('cruiseOrderRel',function ($_query)use ($params){
                                                                   $_query->where(
                                                                       'shopId',$params->shopId
                                                                   )->where('status',CruiseOrderModel::STATUS_EXPIRED);
                                                               });
                                                           });
                                                           break;
                                                       case CruiseOrderModel::STATUS_AUDIT_OK:
                                                           $query->where(function ($query) use ($params){
                                                               $query->whereHas('cruiseOrderRel',function ($_query)use ($params){
                                                                   $_query->where(
                                                                       'shopId',$params->shopId
                                                                   )->where('status',CruiseOrderModel::STATUS_AUDIT_OK);
                                                               });
                                                           });
                                                           break;
                                                       case CruiseOrderModel::STATUS_AUDIT_ERROR:
                                                           $query->where(function ($query)use ($params){
                                                               $query->whereHas('cruiseOrderRel',function ($_query)use ($params){
                                                                   $_query->where(
                                                                       'shopId',$params->shopId
                                                                   )->where('status',CruiseOrderModel::STATUS_AUDIT_ERROR);
                                                               });
                                                           });
                                                           break;
                                                   }
                                               })
                                               ->when(checkFieldLen($params, "startDate"),
                                                   function ($query) use ($params) {
                                                       $query->where("createdAt", ">", strtotime($params->startDate));
                                                   })
                                               ->when(checkFieldLen($params, "endDate"),
                                                   function ($query) use ($params) {
                                                       $query->where("createdAt", "<",
                                                           strtotime($params->endDate) + 24 * 60 * 60);
                                                   });

        $paginate = (clone $baseQuery)->orderByDesc("id")->paginate(
            $params->pageSize,
            [
                "id",
                "shopId",
                "templateType",
                "sysTemplate",
                "taskId",
                "date",
                "status",
                "cruiseOrderId",
                "executeStartTime",
                "executeEndTime",
                "createdAt",
                "submitTime",
                "submitUid",
                "submitUsername",
                "checkDetailsId"
            ],
            'pageNum',
            $params->pageNum
        );


        return array_merge([
            "count" => $paginate->total(),
            "list" => ReportListV2Resource::collection($paginate->items()),
        ], $params->pageNum == 1 ? self::getGroupCheckStatistics(clone $baseQuery, $params->state) : []
        );
    }

    /**
     * 聚合状态数据
     *
     * @param Builder $baseQuery
     * @param int $state
     * @return array
     */
    public static function getGroupCheckStatistics(Builder $baseQuery, int $state): array
    {
        $dailyStartCheckCount       = $dailyEndCheckCount = $weekStartCheckCount = $monthStartCheckCount = 0;
        $dailyStartFinishCheckCount = $dailyEndFinishCheckCount = $weekStartFinishCheckCount = $monthStartFinishCheckCount = 0;
            list(
                $dailyStartCheckCount,
                $dailyEndCheckCount,
                $weekStartCheckCount,
                $monthStartCheckCount
                ) = [
                (clone $baseQuery)->where("sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_OPEN)->count(),
                (clone $baseQuery)->where("sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_CLOSE)->count(),
                (clone $baseQuery)->where("sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_WEEK)->count(),
                (clone $baseQuery)->where("sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_MONTH)->count(),
            ];
            switch ($state) {
                case CruiseCheckSelfDetailModel::CUSTOM_STATE_0:// 全部
                    $finishQuery = (clone $baseQuery)->whereHas('cruiseOrderRel',function ($_query){
                        $_query->whereIn('status',[
                            CruiseOrderModel::STATUS_NOT_REVIEW,
                            CruiseOrderModel::STATUS_AUDIT_OK,
                            CruiseOrderModel::STATUS_AUDIT_ERROR,
                        ]);
                    });
                    list(
                        $dailyStartFinishCheckCount,
                        $dailyEndFinishCheckCount,
                        $weekStartFinishCheckCount,
                        $monthStartFinishCheckCount
                        ) = [
                        (clone $finishQuery)->where("sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_OPEN)
                                            ->count(),
                        (clone $finishQuery)->where("sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_CLOSE)
                                            ->count(),
                        (clone $finishQuery)->where("sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_WEEK)
                                            ->count(),
                        (clone $finishQuery)->where("sysTemplate", CruiseTemplateModel::SYS_TEMPLATE_SELF_MONTH)
                                            ->count(),
                    ];
                    break;
            }

            return [
                "checkGroupCount"       => compact(
                    "dailyStartCheckCount",
                    "dailyEndCheckCount",
                    "weekStartCheckCount",
                    "monthStartCheckCount"
                ),
                "checkGroupFinishCount" => compact(
                    "dailyStartFinishCheckCount",
                    "dailyEndFinishCheckCount",
                    "weekStartFinishCheckCount",
                    "monthStartFinishCheckCount"
                )
            ];
    }

}
